Conversation
The Pub/Sub Pull operator, sensor and trigger hardcoded return_immediately=True, which relies on a Pull option Google deprecated because it can return zero messages while a backlog exists. Users had no way to opt into the long-polling behaviour Google recommends instead. Keeping True as the default preserves existing behaviour, so the change is paired with a deprecation warning announcing the coming flip.
Warning only when a user passes the option leaves the people who most need the notice -- everyone still on the implicit default -- hearing nothing, and it nags the users who already made a deliberate choice. Inverting it also lets the argument stay absent from a call without silently taking the deprecated path. PubsubPullTrigger gains the same treatment. Nothing covered it before, yet it is constructed directly by the google+pubsub scheme for asset watchers, so those Dag authors were getting the deprecated default with nothing telling them. It names the subscription in its message because it is built inside MessageQueueTrigger.serialize(), where stacklevel=2 resolves to common.messaging's file rather than the user's watcher. The operator and the sensor cannot do the same: subscription is a template field there, so at __init__ time it can still hold an unrendered Jinja expression. Only the message text is shared, in one constant. The warn call stays in each class: fixup_decorator_warning_stack only adjusts the stack for modules that define an operator, so moving the call out of them would break the frame the warning points at. The tests drop a module-level filterwarnings mark that silenced every return_immediately deprecation in these files, and start asserting that an unset argument still resolves to True -- the backward-compatibility contract of the deprecation, which nothing pinned.
MessageQueueTrigger.serialize() builds a PubsubPullTrigger from the keyword arguments it was given, so a google+pubsub watcher that omits return_immediately warns during Dag serialization, in the Dag processor rather than in any task log. The examples are rendered into the operator and message-queues guides, so they were teaching the pattern the deprecation steers users away from.
Two things reach users and neither is visible from the release notes otherwise: the new deprecation warning, which for asset watchers appears in Dag processor logs where nobody looks for it, and the deferrable sensor starting to honour an argument it used to drop on the floor. The operator guide also never said that the operator waits indefinitely in deferrable mode, which is the behaviour most likely to surprise.
Contributor
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
AI Summary
Supersedes #67621, which has been idle since 2026-05-27. The original work is by
@michaelpri10 and is preserved here as the first commit, authored to him.
PubSubPullOperator,PubSubPullSensorandPubsubPullTriggerhardcodedreturn_immediately=True, which relies on a Pull option Google deprecated becauseit can return zero messages while a backlog exists. This makes the option
configurable, keeps
Trueas the default so existing behaviour is preserved, andwarns that the default will flip in the first Google provider major release after
March 31, 2027.
Commits
Make return_immediately configurable for the Pub/Sub modulesWarn when return_immediately is unset rather than when it is setPubsubPullTrigger; shares one message constantSet return_immediately in the Pub/Sub examplesDocument the Pub/Sub return_immediately changes for usersWhat changed relative to #67621
Click here
return_immediatelyis unset, not when it isset. Warning only on explicit use leaves everyone still on the implicit default
hearing nothing, and nags users who already made a deliberate choice. This is the
main decision worth a maintainer's opinion.
PubsubPullTriggeris covered too. It was uncovered, yet thegoogle+pubsubscheme constructs it directly for asset watchers, so those Dag authors silently got
the deprecated default. Its message names the subscription, because the trigger is
built inside
MessageQueueTrigger.serialize()wherestacklevel=2resolves tocommon.messaging's file rather than the user's watcher. The operator and sensordeliberately do not interpolate it —
subscriptionis a template field there, soat
__init__time it can still hold an unrendered Jinja expression, whichvalidate-operators-initrejects.PubSubPullSensornow respectsreturn_immediately. It previouslydropped the argument when handing off to the trigger, so it always behaved as
True. This is a real behaviour change for anyone already usingdeferrable=True, return_immediately=False, and it is called out in the changelog.removal date cannot drift. The
warnings.warncall stays in each class:fixup_decorator_warning_stackonly adjusts the stack for modules that define anoperator, so moving the call out would break the frame the warning points at.
filterwarningsmark that silenced everyreturn_immediatelydeprecation in these files, and added assertions that an unsetargument still resolves to
True— the backward-compatibility contract of thedeprecation, which nothing pinned.
Verification
Providers[google]suite: 5379 passed, 41 skippedbreeze run mypy,breeze build-docs google,prekpre-commit and manual stages: all cleanreturn_immediately=Falseand abacklog pulled messages; with
Trueon an empty subscription returned[]withouthanging; the sensor and async trigger both pulled; an unset construction warned and
resolved to
TrueWas generative AI tooling used to co-author this PR?
Generated-by: Claude Code (Opus 5) following the guidelines